/*
 * @Author: 杰编程 2306248989@qq.com
 * @Date: 2023-08-07 18:43:04
 * @LastEditors: 杰编程 2306248989@qq.com
 * @LastEditTime: 2023-08-07 20:12:05
 * @FilePath: /lesson26/NetCacul/CaculatorClient.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "TcpClient.hpp"
#include "Protocol.hpp"
#include "Ulit.hpp"
#include "Sock.hpp"
#include "Err.hpp"
#include <iostream>



using namespace std;
using namespace protocol_ns;
enum
{
    LEFT,
    OPER,
    RIGHT
};
bool StringToRequest(const string &tmp, Request *req)
{
    string str=tmp;
    string space = " ";
    string empty = "";
    while (str.find(space) != string::npos)
    {
        str.replace(str.find(space), space.length(), empty);
    }
    std::string left, right;
    char op;
    int status = LEFT;

    int i = 0;
    while(i < str.size())
    {
        // if(isdigit(e)) left.push_back;

        switch (status)
        {
        case LEFT:
            if (isdigit(str[i]))
                left.push_back(str[i++]);
            else
                status = OPER;
            break;
        case OPER:
            op = str[i++];
            status = RIGHT;
            break;
        case RIGHT:
            if (isdigit(str[i]))
                right.push_back(str[i++]);
            break;
        }
    }
    req->_x = std::stoi(left);
    req->_y = std::stoi(right);
    req->_op = op;
    return true;
}
static void usage(std::string proc)
{
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}
// ./clinet serverip serverport
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        usage(argv[0]);
        exit(USE_ERR);
    }

    string serverip = argv[1];
    uint16_t serverport = atoi(argv[2]);

    Sock socket;

    // 1.创建套接字，打开网络文件
    socket.Socket();
    // 2.连接
    int cnt = 5;
    while (socket.Connect(serverip, serverport) < 0)
    {
        cout << "连接失败，正在重试连接" << endl;
        if (cnt-- == 0)
            break;
    }
    if (cnt == 0)
        exit(CONNECT_ERR);
    cout << "连接成功" << endl;

    while (true)
    {
        cout << "Enter>>>";
        string tmp;
        getline(cin, tmp);
        Request req;
        StringToRequest(tmp, &req);

        // std::cout << "data1# ";
        // std::cin >> req._x;
        // std::cout << "data2# ";
        // std::cin >> req._y;
        // std::cout << "op# ";
        // std::cin >> req._op;

        // 1.序列化
        string sendingString = req.Serialization();
        // 2.添加报头
        sendingString = AddHeads(sendingString);
        // 3.发送数据
        send(socket.Fd(), sendingString.c_str(), sendingString.size(), 0);
        // 4.获取响应
    START:
        string package;
        string inbuffer;
        int len = ReadStrPackage(socket.Fd(), inbuffer, &package);
        if (len < 0)
            goto START;
        std::string effective_load = RemoveHeads(package, len);
        Response res;
        res.Deserialization(effective_load);
        cout << "retsult: " << res._result << " [code:" << res._code << "]";
    }

    return 0;
}